<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <!-- 
    Props 的概念：

      组件接受到的 prop 列表集合

    Props 的声明：
      
      1. 数组语法
        props: [propA, propB]
      2. 对象语法
        props: {
          propA: String,    // propA 必须传递 字符串 类型
          propB: {
            type: String    // 类型
          },
          propC: {
            type: String,
            default: '默认值', // 默认值
          },
          propD: {
            type: String,
            required: true, // 必须传递
          },
          propE: {
            type: String,
            validator(value) {    // 校验函数
              // value 就是传递过来的 prop 的值

              // 函数内需要返回一个 boolean 
              //  true 则说明这个 value 满足要求。否则会报错
            }
          }
        }

    Props 的默认值设置的注意事项：
        如果默认值是引用类型的话，需要通过函数来返回。
        原因与 data 选项必须通过函数返回对象的原因一样：

          组件是可以服用的，期望多次使用之后这些实例之间不要互相影响，如果不通过函数来返回的话，多个实例之间使用的将是同一个内存地址的数据。

     
    Data 选项必须是一个函数返回对象的形式：
        Vue3 任何组件都要遵循这个规则
        Vue2 根组件，也就是 new Vue 时传递的组件可以不用这条规则
   -->

    <div id="app">
      <hello name="张三" :age="18" sex="不详" :is-good="false"></hello>
    </div>

    <script type="module">
      import { createApp } from "./lib/vue3.esm.browser.js";

      const app = createApp({});

      app.component("Hello", {
        // props 声明
        props: {
          name: String,
          age: [String, Number], // 两个类型都可以
          sex: {
            type: String,
            default: "女", // 默认为 女

            validator(value) {
              console.log("自定义校验 sex", value);
              return ["男", "女"].includes(value);
            },
          },
          love: {
            type: Array,
            default() {
              return ["吃饭", "睡觉"];
            },
          },
          isGood: {
            type: Boolean,
            required: true, // 该 Prop 必须传递
          },
        },

        template: `
          <div>
            <h2>Hello</h2>  
          </div>
        `,
      });

      app.mount("#app");
    </script>
  </body>
</html>
